/******************************************************************************
 *
 * Project:		mGameEngine
 * File:		thread.h
 * Author:		karooolek
 * Created on:	2009-01-06
 *
 ******************************************************************************/

#ifndef THREAD_H_
#define THREAD_H_

#include "types.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <pthread.h>
#include <unistd.h>
#endif

/**
 * Abstract base class for creating threads in multi-threaded applications.
 * In order to create own thread, you must derive from Thread and
 * override its _run() method.
 */
class Thread
{
protected:
#ifdef WIN32
	/**
	 * Thread entry function.
	 */
	static DWORD WINAPI _threadEntry(LPVOID);

	/**
	 * Thread handle.
	 */
	HANDLE _thread;
#else
	/**
	 * Thready entry function.
	 * @param thread thread to run.
	 */
	static void *_threadEntry(void *thread);

	/**
	 * Thread handle.
	 */
	pthread_t _thread;

	/**
	 * Suspension mutex.
	 */
	pthread_mutex_t _suspended;

#endif
	/**
	 * Stop request.
	 */
	bool _stop;

	/**
	 * Run thread.
	 */
	virtual void _run() = 0;

	/**
	 * Sleep (cease execution) for specified time.
	 * @param sec sleep time in seconds
	 */
	void _sleep(float sec);

public:
	/**
	 * Create new thread.
	 * New thread doesn't start itself.
	 * start() must be called explicitly.
	 */
	Thread();

	/**
	 * Destroy thread.
	 */
	virtual ~Thread();

	/**
	 * Start thread execution.
	 */
	void start();

	/**
	 * Execute thread in current context.
	 */
	void exec();

	/**
	 * Send stop request to thread.
	 */
	void stop();

	/**
	 * Terminate thread execution.
	 * Dangerous, should be used only in extreme cases!
	 */
	void terminate();

	/**
	 * Resume thread execution.
	 */
	void resume();

	/**
	 * Suspend thread execution.
	 */
	void suspend();

	/**
	 * Join thread.
	 * Waits until thread finishes.
	 */
	void join() const;
};

#endif // THREAD_H_
